package drawingBoard.tool;

import drawingBoard.ImageFrame;
import drawingBoard.ImageService;
import drawingBoard.MyImage;
import drawingBoard.state.EndState;
import drawingBoard.state.MiddleState;
import drawingBoard.state.StartState;
import drawingBoard.memento.CareTaker;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

/**
 * 抽象工具类 AbstractTool
 * 实现接口 Tool
 * 依赖类：ImageFrame
 * 协作类：MyImage
 */
public abstract class AbstractTool implements Tool {
	private ImageFrame frame = null;
	public static int drawWidth = 0; //定义画板的宽
	public static int drawHeight = 0; //定义画板的高
	private Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR); //定义默认鼠标指针
	private int pressX = -1; //按下鼠标的x坐标
	private int pressY = -1; //按下鼠标的y坐标

	public static Color color = Color.BLACK; //颜色

	public AbstractTool(ImageFrame frame) { //构造器
		this.frame = frame;
		//frame.getBufferedImage()返回MyImage对象
		AbstractTool.drawWidth = frame.getBufferedImage().getWidth();
		AbstractTool.drawHeight = frame.getBufferedImage().getHeight();
	}

	public AbstractTool(ImageFrame frame, String path) {
		this(frame);
		//创建工具鼠标图型
		this.defaultCursor = ImageService.createCursor(path);
	}

	public ImageFrame getFrame() { //获取ImageFrame
		return this.frame;
	}

	public Cursor getDefaultCursor() { //获取默认鼠标指针
		return this.defaultCursor;
	}

	public void setDefaultCursor(Cursor cursor) { //设置默认鼠标指针
		this.defaultCursor = cursor;
	}

	public void setPressX(int x) { //设置横坐标
		this.pressX = x;
	}

	public void setPressY(int y) { //设置纵坐标
		this.pressY = y;
	}

	public int getPressX() { //获取横坐标
		return this.pressX;
	}

	public int getPressY() { //获取纵坐标
		return this.pressY;
	}

	public void mouseDragged(MouseEvent e) { //拖动鼠标
		//拖动图形边界
		dragBorder(e);
	}

	public void mouseMoved(MouseEvent e) { //移动鼠标
		//获取鼠标现在的x与y坐标
		int x = e.getX();
		int y = e.getY();
		//获取默认鼠标指针
		Cursor cursor = getDefaultCursor();
		//如果鼠标指针在右下角
		if (x > AbstractTool.drawWidth - 4 && x < AbstractTool.drawWidth + 4 && y > AbstractTool.drawHeight - 4
				&& y < AbstractTool.drawHeight + 4) {
			//将鼠标指针改变为右下拖动形状
			cursor = new Cursor(Cursor.NW_RESIZE_CURSOR);
		}
		//如果鼠标指针在右中
		if (x > AbstractTool.drawWidth - 4 && x < AbstractTool.drawWidth + 4
				&& y > (int) AbstractTool.drawHeight / 2 - 4 && y < (int) AbstractTool.drawHeight / 2 + 4) {
			//将鼠标指针改变为右拖动形状
			cursor = new Cursor(Cursor.W_RESIZE_CURSOR);
		}
		//如果鼠标指针在下中
		if (y > AbstractTool.drawHeight - 4 && y < AbstractTool.drawHeight + 4
				&& x > (int) AbstractTool.drawWidth / 2 - 4 && x < (int) AbstractTool.drawWidth / 2 + 4) {
			//将鼠标指针改变为下拖动形状
			cursor = new Cursor(Cursor.S_RESIZE_CURSOR);
		}
		//设置鼠标指针类型
		getFrame().getDrawSpace().setCursor(cursor);
	}

	public void mouseReleased(MouseEvent e) { //松开鼠标
		//画图
		Graphics g = getFrame().getBufferedImage().getGraphics();
		createShape(e, g);
		//把pressX与pressY设置为初始值
		setPressX(-1);
		setPressY(-1);
		//重绘
		getFrame().getDrawSpace().repaint();
		//备忘录模式增加状态
		takeEffect(getFrame());
		getFrame().originator.setState(getFrame().getBufferedImage());
		getFrame().careTaker.add(getFrame().originator.saveStateToMemento());
		//状态模式
		if (CareTaker.getInstance().index == 0) {
			StartState startState = new StartState();
			startState.doAction(ImageFrame.getInstance().context);
		} else if (CareTaker.getInstance().index == CareTaker.getInstance().size() - 1) {
			EndState endState = new EndState();
			endState.doAction(ImageFrame.getInstance().context);
		} else {
			MiddleState middleState = new MiddleState();
			middleState.doAction(ImageFrame.getInstance().context);
		}
	}

	private void createShape(MouseEvent e, Graphics g) { //画图
		//如果位置在画布内
		if (getPressX() > 0 && getPressY() > 0 && e.getX() > 0 && e.getX() < AbstractTool.drawWidth && e.getY() > 0
				&& e.getY() < AbstractTool.drawHeight) {
			//将整张图片重画
			g.drawImage(getFrame().getBufferedImage(), 0, 0, AbstractTool.drawWidth, AbstractTool.drawHeight, null);
			//设置颜色
			g.setColor(AbstractTool.color);
			getFrame().getBufferedImage().setIsSaved(false);
			//画图形
			draw(g, getPressX(), getPressY(), e.getX(), e.getY());
		}
	}

	public void mousePressed(MouseEvent e) {  //按下鼠标
		//如果位置在图片范围内，设置按下的坐标
		if (e.getX() > 0 && e.getX() < AbstractTool.drawWidth && e.getY() > 0 && e.getY() < AbstractTool.drawHeight) {
			setPressX(e.getX());
			setPressY(e.getY());
		}
	}

	public void mouseClicked(MouseEvent e) {  //点击
	}

	public void draw(Graphics g, int x1, int y1, int x2, int y2) {  //绘图
	}

	public static void takeEffect(ImageFrame imageFrame) {  //使改变生效
		int x = AbstractTool.drawWidth;
		int y = AbstractTool.drawHeight;
		MyImage img = new MyImage(x, y, BufferedImage.TYPE_INT_RGB);
		Graphics g = img.getGraphics();
		g.setColor(Color.WHITE);
		g.drawImage(imageFrame.getBufferedImage(), 0, 0, AbstractTool.drawWidth, AbstractTool.drawHeight, null);
		imageFrame.setBufferedImage(img);
	}

	private void dragBorder(MouseEvent e) {  //拖动图形边界
		getFrame().getBufferedImage().setIsSaved(false);
		//获取鼠标现在的x与y坐标
		int cursorType = getFrame().getDrawSpace().getCursor().getType();
		int x = cursorType == Cursor.S_RESIZE_CURSOR ? AbstractTool.drawWidth : e.getX();
		int y = cursorType == Cursor.W_RESIZE_CURSOR ? AbstractTool.drawHeight : e.getY();
		MyImage img = null;
		//如果鼠标指针是拖动状态
		if ((cursorType == Cursor.NW_RESIZE_CURSOR || cursorType == Cursor.W_RESIZE_CURSOR
				|| cursorType == Cursor.S_RESIZE_CURSOR) && (x > 0 && y > 0)) {
			//改变图像大小
			img = new MyImage(x, y, BufferedImage.TYPE_INT_RGB);
			Graphics g = img.getGraphics();
			g.setColor(Color.WHITE);
			g.drawImage(getFrame().getBufferedImage(), 0, 0, AbstractTool.drawWidth, AbstractTool.drawHeight, null);
			getFrame().setBufferedImage(img);
			//设置画布的大小
			AbstractTool.drawWidth = x;
			AbstractTool.drawHeight = y;
			//设置viewport
			ImageService.setViewport(frame.getScroll(), frame.getDrawSpace(), x, y);
		}
	}
}
